- [Introduction](#introduction)
- [Basic information](#basic-information)
- [Add package to GNU Guix](#add-package-to-gnu-guix)
  - [Calculate project hashsums](#calculate-project-hashsums)
- [Testing the package definition](#testing-the-package-definition)
  - [Generate pre-installation environment script](#test-package-generate-pre-installation-environment-script)
  - [Checking GNU Guix for errors](#test-package-checking-gnu-guix-for-errors)
  - [Testing build and installation of the package](#test-package-testing-build-and-installation-of-the-package)
- [Process of creating a git patch](#process-of-creating-a-git-patch)
  - [Creating a commit](#process-of-creating-a-git-patch-creating-a-commit)
  - [Creating a git patch file](#process-of-creating-a-git-patch-creating-a-git-patch-file)
  - [Sending the patch](#process-of-creating-a-git-patch-sending-the-patch)



<a id="introduction"></a>

# Introduction

This guide aims to summarize things to look out for, when trying to get a package onto the official GNU Guix package manager repository. It contains important points from the following documentation pages and pages these pages link to:

-   [Direct Checkout Hacking](https://guix.gnu.org/cookbook/en/html_node/Direct-checkout-hacking.html)
-   [Packaging Guidelines](https://guix.gnu.org/manual/en/html_node/Packaging-Guidelines.html)
-   [Submitting Patches](https://guix.gnu.org/manual/en/html_node/Submitting-Patches.html)


<a id="basic-information"></a>

# Basic information

-   GNU Guix packages are defined in the code of GNU Guix itself. Many packages are defined in files like [guile-xyz.scm](https://git.savannah.gnu.org/cgit/guix.git/tree/gnu/packages/guile-xyz.scm) or [guile.scm](https://git.savannah.gnu.org/cgit/guix.git/tree/gnu/packages/guile.scm). Therein one can find examples of how to define a package.

-   Changes to the GNU Guix repository can be send to the `guix-patches@gnu.org` mailing list as patches.

-   Patches need to conform to certain guidelines, to be accepted.


<a id="add-package-to-gnu-guix"></a>

# Add package to GNU Guix

Adding a package to GNU Guix consists of 2 steps:

1.  Clone the repository:

    ```shell
    git clone https://git.savannah.gnu.org/git/guix.git
    ```

2.  Edit `gnu/packages/guile-xyz.scm` to add your package definition. `gnu/packages/guile-xyz.scm` should be in the root directory of the GNU Guix source tree.

For an example package definition see [example-package-definition.scm](example-package-definition.scm). Furthermore the source code of GNU Guix also contains some snippets at `etc/snippets/scheme-mode/`, which might be of use for `yasnippet` users. Some of them are used for creating commit messages, which fit the GNU Guix maintainers' wishes.


<a id="calculate-project-hashsums"></a>

## Calculate project hashsums

GNU Guix makes extensive use of hashsums for verifying integrity of packages. When creating a package or creating a patch for an existing package, calculation of the correct hashsum is required.

The correct way to calculate the hash of a package depends on what method is used to fetch the package. The methods of fetching the package are documented at <https://guix.gnu.org/manual/en/html_node/origin-Reference.html>.


### Using git-fetch method

If one uses `(method git-fetch)` in the package definition, one needs to calculate the hash of a package using the following command inside the root directory of the package's source code:

```shell
guix hash --exclude-vcs --serializer=nar .
```


#### TODO Open questions

What format does one need to use?

```shell
guix hash --exclude-vcs --serializer=nar --format=??? .
```

Is the default one correct?

Or does one need to specify `base32`?


### Using url-fetch method

If one uses `(method url-fetch)` in the package definition, referencing a release tarball (`tar.gz`), one needs to calculate the hash of a package using the following command:

```shell
guix download <URL OF RELEASE TARBALL>
```


<a id="testing-the-package-definition"></a>

# Testing the package definition

Once the package definition is written into the GNU Guix sources, there is a testing facility one should use (official reference: [Running Guix Before It Is Installed](https://guix.gnu.org/manual/en/html_node/Running-Guix-Before-It-Is-Installed.html)), before submitting patches for integration of the package into the official GNU Guix repository. This is to make sure, that the package will work for other people, who try to install it using the GNU Guix package manager.

Instead of testing by installing a modified GNU Guix on a system to test the distribution, there is a way of testing without installing it, by using a script `pre-inst-env`. This script is not contained directly within the GNU Guix sources. It needs to be generated.

In the following some commands will be prefixed with `guix environment guix --`. Instead of prefixing each command, which is supposed to run inside this GNU Guix environment, it might be simpler to enter such an environment once, for example by running `guix environment guix` and then run commands inside the environment, without leaving it. This guide chooses to invoke `guix environment guix` for each command, where the command should be run inside the guix environment, to make it explicitly clear, when that is the case and to keep the commands stand-alone copy-paste-able.


<a id="test-package-generate-pre-installation-environment-script"></a>

## Generate pre-installation environment script

There is a pre-installation environment script, which helps with testing the package, but it needs to be generated at first. The script has some prerequisites itself. It will not work out of the box and needs to be run inside a specific GNU Guix environment, which in turn means, that you will need GNU Guix installed on the system to test on GNU Guix packages using the GNU Guix source tree<sup><a id="fnr.1" class="footref" href="#fn.1" role="doc-backlink">1</a></sup>.

The next mandatory step is to install GNU Guix on your system. Refer to [Binary Installation](https://guix.gnu.org/manual/en/html_node/Binary-Installation.html).

To generate it the `pre-int-env` script, one needs to run the following commands in the root directory of GNU Guix:

```shell
guix shell --development guix -- ./bootstrap
guix shell --development guix -- ./configure --localstatedir=/var
```

`guix environment guix --` makes sure to be in an environment, that has no environment variables set from the current shell and installs the dependencies of GNU Guix, which are required for development. This part of the command will drop into a shell, in which `./configure` then runs.

After successfully running the above commands, the root directory of the GNU Guix source tree should contain a script called `pre-inst-env`.


<a id="test-package-checking-gnu-guix-for-errors"></a>

## Checking GNU Guix for errors

Since the GNU Guix sources have been modified, it is necessary to run tests to check if things are still working fine. This is done by running the following command:

```shell
guix shell --development guix -- make check
```

Again we use the environment with all things required for GNU Guix in it. Then we call `make check` inside that environment. GNU Make is already an input to `guix`, which makes it unnecessary to write `guix environment guix --ad-hoc make -- make check` instead. To use multiple CPU cores and save some time one can use the `-j` argument to `make` as in `make check -j8`. For example as follows:

```shell
guix shell --development guix -- make check -j$(nproc)
```

There is no need to run `make all` or `make` here, because `make check` already implies a call of `make all` or `make`.


<a id="test-package-testing-build-and-installation-of-the-package"></a>

## Testing build and installation of the package

The package has been added to the GNU Guix sources and GNU Guix has been tested using its test suite. The next step is to test, whether the build and installation of the added package succeed.

Again the commands used for checking build and installation will be run inside the GNU Guix environment created by running `guix environment guix`.

In this step the `pre-inst-env` script, which has been generated before, will be used to run GNU Guix commands.

Prefix GNU Guix commands with `./pre-inst-env` to run them in an environment using the local GNU Guix source tree, instead of the potentially installed GNU Guix package manager. The idea is to make sure the environment is clean, ensuring, that no machine specific configuration exerts an influence on the success or failure of the build or installation of the package.


### Testing build of the package

The instructions at [Packaging Guidelines](https://guix.gnu.org/manual/en/html_node/Packaging-Guidelines.html) tell to run `./pre-inst-env guix build guile-fslib --keep-failed` to test package definitions. However, it is important to note, this kind of command needs to be run inside the environment created by `guix environment guix`!

To test the build process of the package run the following command:

```shell
guix shell --development guix -- \
    ./LOCATION_OF_GUIX_SOURCES/pre-inst-env \
         guix build \
         --keep-failed \
         <package name>
```

For example for `guile-fslib` from inside the GNU Guix sources root directory one would run the following command:

```shell
guix shell --development guix -- \
    ./pre-inst-env \
         guix build \
         --keep-failed \
         --log-file \
         guile-fslib
```

The `--log-file` might need to be dropped for the command to work, if GNU Guix complains about missing the log file.

If there are errors or the package cannot be found, the guides mention how one can try to debug the package definition:

> If the package is unknown to the guix command, it may be that the source file contains a syntax error, or lacks a define-public clause to export the package variable. To figure it out, you may load the module from Guile to get more information about the actual error:
>
> ./pre-inst-env guile -c '(use-modules (gnu packages gnew))'
>
> &#x2013; <https://guix.gnu.org/manual/en/html_node/Packaging-Guidelines.html>


### Testing installation of the package

To make sure the installation is working as well, the following command is tried:

```shell
guix shell --development guix -- \
    ./LOCATION_OF_GUIX_SOURCES/pre-inst-env \
         guix install \
         <package name>
```

So for example for `guile-fslib` one would try the following command from inside the GNU Guix sources root directory:

```shell
guix shell --development guix -- ./pre-inst-env guix install guile-fslib
```

If this and all previous tests worked, the package definition can be send in as a patch.


<a id="process-of-creating-a-git-patch"></a>

# WIP Process of creating a git patch

Now, that there is a tested and hopefully functioning package definition inside the GNU Guix sources, a git patch needs to be created. In the following the required steps for creating a git patch according to the guidelines of the GNU Guix project are explained.


<a id="process-of-creating-a-git-patch-creating-a-commit"></a>

## Creating a commit

To create a patch, the changes made to need to be put into a git commit. This commit does not have to be pushed (and probably cannot be pushed, unless permissions to do so are available). It is sufficient to have the commit existing locally.

The guilelines for the changelog style commit messages demand are described at [Change Logs](https://www.gnu.org/prep/standards/html_node/Change-Logs.html#Change-Logs). However, in the context of GNU Guix package manager, the guidelines are not to be taken literally and answered one by one. Instead there are snippets in the GNU Guix sources, located at:

-   `etc/snippets/scheme-mode`
-   `etc/snippets/text-mode`

The directory `etc/snippets/text-mode` contains the snippets for various types of commit messages, like adding a new package or updating an existing package and their format is the format, which is usually expected for patches, which one sends to the Guix patches mailing list.

These are snippet definition files for `yasnippet`, an Emacs extension package, which deals with snippet expansion. Thus one good way to create conforming commit messages is to use Emacs, `yasnippet` and in addition to that perhaps `magit`, to integrate with `git` or setting emacs as editor for git<sup><a id="fnr.2" class="footref" href="#fn.2" role="doc-backlink">2</a></sup>.


<a id="process-of-creating-a-git-patch-creating-a-git-patch-file"></a>

## Creating a git patch file

Once the commit is in place, the git patch file can be created. Patches can be created using the following command:

```shell
git format-patch --minimal --diff-algorithm=minimal --progress <previous commit id>
```

`<previous commit id>` is the id of the commit before commit containing the changes made to add the package.


<a id="process-of-creating-a-git-patch-sending-the-patch"></a>

## Sending the patch

All that is left is sending the patch to the GNU Guix project maintainers. The GNU Guix project has a specialized mailing list for this purpose: `guix-patches@gnu.org`. Sending a patch to this mailing list will cause a tracking number to be assigned to the patch, so that all future communication regarding the patch can be grouped using that tracking number.

You have 2 options to send the patch to that e-mail address. The first option is to copy the text of the patch and use that as message content. The second option is to attach the patch as an attachment to the e-mail. The second option is preferred, as it might be a more reliable process to process the attachment of an e-mail, than it is to extract the patch from the message body of the e-mail.

For instructions on how to respond to patches using the tracking number or sending multiple patches tracked by the same number see the official documentation at [Submitting Patches](https://guix.gnu.org/manual/en/html_node/Submitting-Patches.html) and [Sending a Patch Series](https://guix.gnu.org/manual/en/html_node/Submitting-Patches.html#Sending-a-Patch-Series).

## Footnotes

<sup><a id="fn.1" class="footnum" href="#fnr.1">1</a></sup> The snake is kind of biting its own tail here, because we use an installed `guix` to create a temporary environment, to run the bootstrap script. However, since the task at hand is to add a package to an existing and installable GNU Guix package manager, it is not necessary to worry about how the bootstrapping behind building the package manager for the first time worked.

<sup><a id="fn.2" class="footnum" href="#fnr.2">2</a></sup> Such as `git config core.editor emacs`.